package com.gress.shop.util;

import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * 日期的工具类.
 *
 * @author dcross
 */
public class DateUtil {

    /**
     * 默认的日期格式
     */
    public static String DEFAULT_DATE_FORMAT = "yyyy-MM-dd";

    public static String yyyyMMddHHmmss = "yyyyMMddHHmmss";
    public static String YYMMDD_HHmm = "yyyy-MM-dd HH:mm";
    public static String YYMMDD_HHmmSS = "yyyy-MM-dd HH:mm:ss";

    /**
     * <code>把日期格式化为时期时间格式</code>.
     */
    public static final DateFormat DATETIME_FORMAT = new SimpleDateFormat(YYMMDD_HHmmSS);

    /**
     * <code>把日期格式化为时期时间格式</code>.
     */
    public static final DateFormat DATETIME_FORMAT2 = new SimpleDateFormat(YYMMDD_HHmm);


    /**
     * <code>把日期格式化为时期时间格式</code>.
     */
    public static final DateFormat DATETIME_FORMAT3 = new SimpleDateFormat("HH:mm");

    /**
     * 将日期转换成指定格式的字符串
     *
     * @param date       - 要转换的日期
     * @param dateFormat - 日期格式
     * @return String 日期对应的字符串
     */
    public static String convertDate2String(Date date, String dateFormat) {
        SimpleDateFormat sdf = null;
        if (dateFormat != null && !dateFormat.equals("")) {
            try {
                sdf = new SimpleDateFormat(dateFormat);
            } catch (Exception e) {
                sdf = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
            }
        } else {
            sdf = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
        }
        return sdf.format(date);
    }

    /**
     * 将日期(java.sql.Date)转换成指定格式的字符串
     *
     * @param date       要转换的日期
     * @param dateFormat 日期格式
     * @return String 日期对应的字符串
     */
    public static String convertDate2String(java.sql.Date date, String dateFormat) {
        SimpleDateFormat sdf = null;
        if (dateFormat != null && !dateFormat.equals("")) {
            try {
                sdf = new SimpleDateFormat(dateFormat);
            } catch (Exception e) {
                sdf = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
            }
        } else {
            sdf = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
        }
        return sdf.format(date);
    }

    /**
     * 将日期转换成指定格式的字符串
     *
     * @param date - 要转换的日期
     * @return String 日期对应的字符串
     */
    public static String convertDate2String(Date date) {
        SimpleDateFormat sdf = null;
        sdf = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
        return sdf.format(date);
    }

    /**
     * 将字符串转换成日期
     *
     * @param stringDate - 要转换的字符串格式的日期
     * @return Date 字符串对应的日期
     */
    public static Date convertString2Date(String stringDate) {
        return convertString2Date(stringDate, DEFAULT_DATE_FORMAT);
    }

    /**
     * 将字符串转换成日期
     *
     * @param stringDate - 要转换的字符串格式的日期
     * @param dateFormat - 要转换的字符串对应的日期格式
     * @return Date 字符串对应的日期
     */
    public static Date convertString2Date(String stringDate, String dateFormat) {
        if (StringUtils.isNotBlank(stringDate)) {
            SimpleDateFormat sdf = null;
            if (dateFormat != null && !dateFormat.equals("")) {
                try {
                    sdf = new SimpleDateFormat(dateFormat);
                } catch (Exception e) {
                    sdf = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
                }
            } else {
                sdf = new SimpleDateFormat(DEFAULT_DATE_FORMAT);
            }
            try {
                return sdf.parse(stringDate);
            } catch (ParseException e) {
                return new Date(System.currentTimeMillis());
            }
        } else {
            return null;
        }
    }

    /**
     * 获取当前日期前后N天.
     *
     * @param currDate  当前日期
     * @param type      类型(AGO:前十天,AFTER:后十天)
     * @param dayEndNum 天数（范围边界值）
     * @return the curr day
     */
    public static List<String> getCurrDay(Date currDate, String type, int dayEndNum) {
        List<String> list = new ArrayList<String>();

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance(Locale.CANADA);
        calendar.setTime(currDate);
        // if (type.equals("AGO")) {
        list.add(format.format(calendar.getTime()));
        // }
        for (int i = 1; i < dayEndNum; i++) {
            if (StringUtils.isNotBlank(type)) {
                if (type.equals("AGO")) {
                    calendar.add(Calendar.DAY_OF_MONTH, -1);
                    list.add(format.format(calendar.getTime()));
                } else if (type.equals("AFTER")) {
                    calendar.add(Calendar.DAY_OF_MONTH, 1);
                    list.add(format.format(calendar.getTime()));
                }
            }
        }
        return list;
    }

    /**
     * 获取当前日期前后十周.
     *
     * @param currDate 当前日期
     * @param type     类型(AGO:前十周,AFTER:后十周)
     * @return the curr after10 weeks
     */
    public static List<String> getCurr10Weeks(Date currDate, String type) {
        List<String> list = new ArrayList<String>();

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
        Calendar calendar = Calendar.getInstance(Locale.CANADA);
        calendar.setTime(currDate);
        // 得到今天是星期几，星期日为1
        int datInWeek = calendar.get(Calendar.DAY_OF_WEEK);

        // Clone一个新的
        Calendar calendar1 = (Calendar) calendar.clone();

        // 所在周的第一天
        calendar.add(Calendar.DAY_OF_MONTH, -(datInWeek - 2));
        // 所在周的最后一天
        calendar1.add(Calendar.DAY_OF_MONTH, 8 - datInWeek);

        if (type.equals("AGO")) { //$NON-NLS-1$
            list.add(format.format(calendar.getTime()) + ("MULTI_000535"/*至*/) + format.format(calendar1.getTime()));
        }
        for (int i = 0; i < 10; i++) {
            if (StringUtils.isNotBlank(type)) {
                if (type.equals("AGO")) { //$NON-NLS-1$
                    calendar.add(Calendar.DAY_OF_MONTH, -7);
                    calendar1.add(Calendar.DAY_OF_MONTH, -7);
                    list.add(format.format(calendar.getTime()) + ("MULTI_000535"/*至*/) + format.format(calendar1.getTime()));
                } else if (type.equals("AFTER")) { //$NON-NLS-1$
                    calendar.add(Calendar.DAY_OF_MONTH, 7);
                    calendar1.add(Calendar.DAY_OF_MONTH, 7);
                    list.add(format.format(calendar.getTime()) + ("MULTI_000535"/*至*/) + format.format(calendar1.getTime()));
                }
            }
        }
        return list;
    }

    /**
     * 获取当前日期前后十月.
     *
     * @param currDate 当前日期
     * @param type     类型(AGO:前十月,AFTER:后十月)
     * @return the curr ago10 day
     */
    public static List<String> getCurr10Month(Date currDate, String type) {
        List<String> list = new ArrayList<String>();

        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM");
        Calendar calendar = Calendar.getInstance(Locale.CANADA);
        calendar.setTime(currDate);
        if (type.equals("AGO")) {
            list.add(format.format(calendar.getTime()));
        }
        for (int i = 0; i < 10; i++) {
            if (StringUtils.isNotBlank(type)) {
                if (type.equals("AGO")) {
                    calendar.add(Calendar.MONTH, -1);
                    list.add(format.format(calendar.getTime()));
                } else if (type.equals("AFTER")) {
                    calendar.add(Calendar.MONTH, 1);
                    list.add(format.format(calendar.getTime()));
                }
            }
        }
        return list;
    }


    /**
     * 获取当前日期的前3个月
     *
     * @param currDate 当前日期
     * @return
     */
    public static Long getAgoCurr3Month(Date currDate) {
        Date dNow = new Date(); //当前时间
        Date dBefore = new Date();
        Calendar calendar = Calendar.getInstance(); //得到日历
        calendar.setTime(dNow);//把当前时间赋给日历
        calendar.add(calendar.MONTH, -3); //设置为前3月
        return calendar.getTime().getTime(); //得到前3月的时间
    }


    /**
     * 得到某一天的开始时间.
     *
     * @param date 日期.
     * @return
     */
    public static Date getDayStart(Date date) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        return calendar.getTime();
    }

    /**
     * 得到某一天的结束时间.
     *
     * @param date 日期.
     * @return
     */
    public static Date getDayEnd(Date date) {
        if (date == null) {
            return null;
        }
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 59);
        return calendar.getTime();
    }

    /**
     * 根据传入的格式将String类型的日期转换为Long
     *
     * @param dateStr   日期
     * @param formatStr 转换格式
     * @return 返回转换后的Long类型日期
     * @author tianml
     */
    public static Long dateFormat_stringToLong(String dateStr, String formatStr) {
        SimpleDateFormat df = new SimpleDateFormat(formatStr);
        try {
            return df.parse(dateStr).getTime();
        } catch (ParseException e) {
        }
        return null;
    }


    /**
     * 长整型时间转日期类型.
     *
     * @param time 时间数字
     * @return 转换后的日期
     */
    public static long dateTolong(String time) {
        String[] times = time.split(":");
        return Long.parseLong(times[0]) * 60 + Long.parseLong(times[1]);
    }

    /**
     * 获得上月第一天.
     *
     * @return 上月第一天，类型为Date型
     */
    public static Date getBeforeMonthFirstDay() {
        // java.text.SimpleDateFormat format = new
        // java.text.SimpleDateFormat("yyyy-MM-dd");
        Calendar cpcalendar = new GregorianCalendar();
        cpcalendar.add(Calendar.MONTH, -1);
        cpcalendar.set(Calendar.DAY_OF_MONTH, 1);
        // String now = format.format(cpcalendar.getTime());
        return cpcalendar.getTime();
    }

    /**
     * 获得上月最后一天.
     *
     * @return 上月最后一天，类型为Date型
     */
    public static Date getBeforeMonthLastDay() {
        // java.text.SimpleDateFormat format2 = new
        // java.text.SimpleDateFormat("yyyy-MM-dd");
        Calendar cpcalendar = new GregorianCalendar();
        cpcalendar.set(Calendar.DATE, 1);// 设为当前月的1号
        cpcalendar.add(Calendar.DATE, -1);// 减一天，变为上月最后一天
        // java.util.Date date = cpcalendar.getTime();
        // String now = format2.format(date);
        return cpcalendar.getTime();
    }

    /**
     * 得到当天时间的前一天
     */
    public static Date getBeforeDay() {
        Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时间
        calendar.add(Calendar.DATE, -1); // 得到前一天
        return calendar.getTime();
    }

    /**
     * 得到当天时间的前两天
     */
    public static Date getBeforeTwoDay() {
        Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时间
        calendar.add(Calendar.DATE, -2); // 得到前一天
        return calendar.getTime();
    }

    /**
     * 得到当天时间的下一天
     */
    public static Date getNextDay() {
        Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时间
        calendar.add(Calendar.DATE, +1); // 得到下一天
        return calendar.getTime();
    }

    /**
     * 得到当天时间的下d天
     */
    public static Date getPramerDay(int d) {
        Calendar calendar = Calendar.getInstance();// 此时打印它获取的是系统当前时间
        calendar.add(Calendar.DATE, +d); // 得到下d天
        return calendar.getTime();
    }

    /**
     * 根据输入的日期获取 当月的第一天
     *
     * @return
     */
    public static Date getFirstDayOfMonth(long time) {
        Calendar startDate = Calendar.getInstance();
        startDate.setTime(new Date(time));
        startDate.set(Calendar.DATE, 1);// 设为当前月的1号
        startDate.set(Calendar.HOUR_OF_DAY, 0);
        startDate.set(Calendar.MINUTE, 0);
        startDate.set(Calendar.SECOND, 0);
        return startDate.getTime();
    }

    /**
     * 获得距指定时间多少天之后的日期
     *
     * @return
     */
    public static Date getAfterDate(Date date, int days) {

        Calendar now = Calendar.getInstance();
        now.setTime(date);
        now.set(Calendar.DATE, now.get(Calendar.DATE) + days);
        return now.getTime();
    }

    /**
     * 获取当月第一天
     *
     * @return 当月第一天 如 2011-08-01
     */
    public static String getFirstDayOfMonth() {
        String str = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.DATE, 1);// 设为当前月的1号
        str = sdf.format(lastDate.getTime());
        return str;
    }

    /**
     * 获取当月最后一天
     *
     * @return 当月最后一天 如 2011-08-01
     */
    public static String getEndDayOfMonth() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        Calendar cal = Calendar.getInstance();
        cal.set(Calendar.DAY_OF_MONTH, 1);
        cal.add(Calendar.MONTH, 1);
        cal.add(Calendar.DATE, -1);
        return sdf.format(cal.getTime());
    }

    /**
     * 获取某周某天的日期
     *
     * @param beginDay 起始天(周一为0，周日为6)
     * @param week     第几周（当天周为0）
     */
    public static String getDateByBeginDayAndWeek(int beginDay, int week) {
        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus + 7 * week + (beginDay - 1));
        Date monday = currentDate.getTime();
        DateFormat df = DateFormat.getDateInstance();
        String preMonday = df.format(monday);
        return preMonday;
    }

    // 获得当前日期与本周日相差的天数
    private static int getMondayPlus() {
        Calendar cd = Calendar.getInstance();
        // 获得今天是一周的第几天，星期日是第一天，星期二是第二天......
        int dayOfWeek = cd.get(Calendar.DAY_OF_WEEK) - 1; // 因为按中国礼拜一作为第一天所以这里减1
        if (dayOfWeek == 1) {
            return 0;
        } else {
            return 1 - dayOfWeek;
        }
    }


    /**
     * 获取当前日期是星期几<br>
     *
     * @param dt
     * @return 当前日期是星期几
     */
    public static String getWeekOfDate(Date dt) {
        String[] weekDays = {("MULTI_000530"/*星期日*/), ("MULTI_000534"/*星期一*/), ("MULTI_000528"/*星期二*/), ("MULTI_000531"/*星期三*/), ("MULTI_000532"/*星期四*/), ("MULTI_000533"/*星期五*/), ("MULTI_000529"/*星期六*/)}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$ //$NON-NLS-7$
        Calendar cal = Calendar.getInstance();
        cal.setTime(dt);

        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
        if (w < 0)
            w = 0;

        return weekDays[w];
    }

    /**
     * 转成日期时间格式的字符串.
     * <p/>
     * 格式如：'yyyy-MM-dd HH:mm:ss'
     * <p/>
     * .
     *
     * @param date 日期.
     * @return 日期时间格式字符串.
     */
    public static String toDateTime(Date date) {
        if (date == null) {
            return null;
        }
        return DATETIME_FORMAT.format(date);
    }

    /**
     * 日期长整型转换成字符串型<br>
     *
     * @param time 日期
     * @param type 转换的形式(yyyy-MM-dd HH:mm:ss)
     * @return 转换后的日期
     */
    public static String longToString(Long time, String type) {
        SimpleDateFormat df = new SimpleDateFormat(type);
        return df.format(new Date(time));
    }

    // 获得本周一的日期
    public static String getMondayOFWeek() {
        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus);
        Date monday = currentDate.getTime();

        DateFormat df = DateFormat.getDateInstance();
        String preMonday = df.format(monday);
        return preMonday;
    }

    /**
     * 获得本周周末的日期.
     *
     * @return
     */
    public static String getEndWeekday() {
        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus);
        currentDate.add(GregorianCalendar.DATE, 6);
        Date monday = currentDate.getTime();

        DateFormat df = DateFormat.getDateInstance();
        String preMonday = df.format(monday);
        return preMonday;
    }

    // 获得上周星期一的日期
    public static String getPreviousWeekday() {
        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus + 7 * (-1));
        Date monday = currentDate.getTime();
        DateFormat df = DateFormat.getDateInstance();
        String preMonday = df.format(monday);
        return preMonday;
    }

    /**
     * 获取上月第一天的日期
     *
     * @return 上月第一天 如 2011-07-01
     */
    public static String getPreviousMonthFirst() {
        String str = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar lastDate = Calendar.getInstance();
        lastDate.set(Calendar.DATE, 1);// 设为当前月的1号
        lastDate.add(Calendar.MONTH, -1);// 减一个月，变为下月的1号
        // lastDate.add(Calendar.DATE,-1);//减去一天，变为当月最后一天

        str = sdf.format(lastDate.getTime());
        return str;
    }


    /**
     * 获取上月最后一天的日期
     *
     * @return 上月最后一天 如 2011-07-31
     */
    public static String getPreviousMonthEnd() {
        String str = "";
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

        Calendar lastDate = Calendar.getInstance();
        lastDate.add(Calendar.MONTH, -1);// 减一个月
        lastDate.set(Calendar.DATE, 1);// 把日期设置为当月第一天
        lastDate.roll(Calendar.DATE, -1);// 日期回滚一天，也就是本月最后一天
        str = sdf.format(lastDate.getTime());
        return str;
    }

    // 获得上周星期日的日期
    public static String getPreviousWeekSunday() {
        int mondayPlus = getMondayPlus();
        GregorianCalendar currentDate = new GregorianCalendar();
        currentDate.add(GregorianCalendar.DATE, mondayPlus + (-1));
        Date monday = currentDate.getTime();
        DateFormat df = DateFormat.getDateInstance();
        String preMonday = df.format(monday);
        return preMonday;
    }

    // 获得去掉时间的日期
    public static Date getDateWithoutTime(Date date) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.SECOND, 0);
        calendar.set(Calendar.MILLISECOND, 0);
        return calendar.getTime();
    }

    /**
     * 获取某时间段前后小时
     *
     * @param date
     * @param offset
     * @return
     */
    public static Date changeHour(Date date, int offset) {
        if (date == null)
            return null;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.set(Calendar.HOUR_OF_DAY, (calendar.get(Calendar.HOUR_OF_DAY) + offset));
        return calendar.getTime();
    }

    /**
     * 得到时间的前后分钟差异.
     *
     * @param date   日期。
     * @param offset 分钟差异.
     * @return
     */
    public static Date dealMinuteDiff(Date date, int offset) {
        if (date == null)
            return null;
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, offset);
        return calendar.getTime();
    }


    /**
     * 判断日期是否在今天之前
     *
     * @param dateFormat
     * @return
     */
    public static boolean isTodayBefore(String dateFormat) {
        Date nowdate = new Date();
        String date = convertDate2String(nowdate, DEFAULT_DATE_FORMAT);
        SimpleDateFormat sdf = new SimpleDateFormat(DEFAULT_DATE_FORMAT,
                Locale.CHINA);
        Date d;
        try {
            d = sdf.parse(dateFormat);
            int flag = d.compareTo(convertString2Date(date));
            if (flag >= 0) {//当天及当天之后，<0就是在日期之前
                return false;
            } else {
                return true;
            }
        } catch (ParseException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 往前提前num月
     *
     * @param start
     * @param num
     * @return 提前后的date
     */
    public static Date dateSubMonth(Date start, int num) {
        Calendar c = Calendar.getInstance();
        c.setTime(start);
        c.set(Calendar.MONTH, c.get(Calendar.MONTH) - num);
        return c.getTime();
    }

    /**
     * 时间比较
     *
     * @param expiredDateStr
     * @param date
     * @return
     */
    public static boolean isPastdue(String expiredDateStr, Date date) {
        if (StringUtils.isBlank(expiredDateStr)) {
            return false;
        }
        Date expiredDate = convertString2Date(expiredDateStr + "235959", yyyyMMddHHmmss);
        return date.compareTo(expiredDate) > 0;
    }

    public static String format(long date, String format) {
        if (date < 0) {
            return "";
        }
        if (StringUtils.isBlank(format)) {
            format = YYMMDD_HHmmSS;
        }
        SimpleDateFormat formater = new SimpleDateFormat(format);
        return formater.format(new Date(date));
    }

    /**
     * 将日期对象解析成字符串
     *
     * @param date
     * @param format 取值如：DateUtil.YYMMDD
     * @return
     */
    public static String formatChange(Date date, String format) {
        SimpleDateFormat formater = new SimpleDateFormat(format);
        return formater.format(date);
    }

    /**
     * 往前提前num天
     *
     * @param start
     * @param num
     * @return 提前后的date
     */
    public static Date dateSub(Date start, int num) {
        Calendar c = Calendar.getInstance();
        c.setTime(start);
        c.set(Calendar.DAY_OF_MONTH, c.get(Calendar.DAY_OF_MONTH) - num);
        return c.getTime();
    }

    public static String getToday() {
        Date date = new Date();
        return convertDate2String(date, "yyyyMMdd");
    }

   /* public  static void main(String arg[]){
        String startDate = DateUtil.formatChange(DateUtil.dateSub(new Date(), 90), "yyyyMMdd");
        String endDate = DateUtil.formatChange(DateUtil.dateSub(new Date(),1),"yyyyMMdd");
        System.out.print(JSON.toJSONString(startDate));
        System.out.print(JSON.toJSONString(endDate));
    }*/
}
